package com.xx.chb01.utils.map;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.Map.Entry;

/**
 * 
 * 实体类转成MAP
 * @author Sim
 *
 */
public class BeanMapUtil {
	
//	public static <T> T toObject(Class<T> clz, Map<String,Object> map) {
//
//		if (clz == Map.class){
//			return (T) map;
//		}
//
//		List<Field> fl = new ArrayList<Field>();
//
//		if (clz.getSuperclass() != Object.class) {
//			fl.addAll(Arrays.asList(clz.getSuperclass().getDeclaredFields()));
//		}
//		fl.addAll(Arrays.asList(clz.getDeclaredFields()));
//
//		T obj = null;
//		try {
//			obj = clz.newInstance();
//		} catch (InstantiationException | IllegalAccessException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
//
//		try {
//
//			for (Field f : fl) {
//
//				int modifiers = f.getModifiers();
//				String key = f.getName();
//
//				if (Modifier.isStatic(modifiers))
//					continue;
//
//				if (Modifier.isFinal(modifiers))
//					continue;
//
//				f.setAccessible(true);
//				Object v = map.get(key);
//				if (v != null){
//					String name = f.getType().getName().toLowerCase();
//					Class fc = f.getType();
//
//					if (name.contains("double")){//MYSQL 方言
//						try{
//							f.set(obj, v);
//						}catch(Exception e){
//							f.set(obj, Double.valueOf(v.toString()));
//						}
//					}else if (name.contains("long") || name.contains("Long") ){
//						if (v instanceof String){
//							Long vL = Long.valueOf((String)v);
//							long vl = vL;
//							f.set(obj, vl);
//						}else{
//							f.set(obj, v);
//						}
//					}else if (name.contains("int") ){
//						if (v instanceof String){
//							Integer vL = Integer.valueOf((String)v);
//							int vl = vL;
//							f.set(obj, vl);
//						}else{
//							f.set(obj, v);
//						}
//					}else if (v instanceof Map){
//						f.set(obj, toObject(fc, (Map) v));
//					}else{
//						if (v instanceof Long && f.getType() == Date.class){
//							f.set(obj, TimeUtil.getDate((Long)v));
//						}else{
//							f.set(obj, v);
//						}
//					}
//				}
//
//			}
//
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//		return obj;
//	}

	public static Map<String, String> toStringMap(Object obj) {

		//java在反射时候经常用到了 Field 类。
		//利用 Field 类 使用反射改变属性值。可以用在修改配置文件上。
		List<Field> fl = new ArrayList<Field>();

		@SuppressWarnings("rawtypes")
		Class clz = obj.getClass();

		if (clz.getSuperclass() != Object.class) {
			fl.addAll(Arrays.asList(clz.getSuperclass().getDeclaredFields()));
		}
		fl.addAll(Arrays.asList(clz.getDeclaredFields()));

		Map<String, String> map = new HashMap<String, String>();

		try {

			for (Field f : fl) {

				int modifiers = f.getModifiers();
				String key = f.getName();

//				if (Modifier.isTransient(modifiers))
//					continue;
				
				if (Modifier.isStatic(modifiers))
					continue;

				if (Modifier.isFinal(modifiers))
					continue;
	
				f.setAccessible(true);
				Object value = f.get(obj);
				
				if (value == null){
					map.put(key, null);
				}else{
					map.put(key, value.toString());
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return map;
	}
	
	public static Map<String, Object> toObjectMap(Object obj) {
		//Class（反射的入口）、Method （成员方法）、Field （成员变量），而我想要实现的功能使用Field即可实现。
		List<Field> fl = new ArrayList<Field>();
		@SuppressWarnings("rawtypes")
		Class clz = obj.getClass();
		//返回直接继承的父类  作用 ： 获取父类的信息
		if (clz.getSuperclass() != Object.class) {
			//将数组转化为list
			fl.addAll(Arrays.asList(clz.getSuperclass().getDeclaredFields()));
		}
		fl.addAll(Arrays.asList(clz.getDeclaredFields()));
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			for (Field f : fl) {
				//返回int类型值表示该字段的修饰符
				int modifiers = f.getModifiers();
				String key = f.getName();
				if (Modifier.isStatic(modifiers))
					continue;
				if (Modifier.isFinal(modifiers))
					continue;
				//得作用就是让我们在用反射时访问私有变量
				f.setAccessible(true);
				Object value = f.get(obj);
				map.put(key, value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	public static Map<String, Object> toObjectMapForPersistence(Object obj) {

		List<Field> fl = new ArrayList<Field>();

		@SuppressWarnings("rawtypes")
		Class clz = obj.getClass();

		if (clz.getSuperclass() != Object.class) {
			fl.addAll(Arrays.asList(clz.getSuperclass().getDeclaredFields()));
		}
		fl.addAll(Arrays.asList(clz.getDeclaredFields()));

		Map<String, Object> map = new HashMap<String, Object>();

		try {

			for (Field f : fl) {

				int modifiers = f.getModifiers();
				String key = f.getName();

				System.out.println(key + "_" + modifiers);


				if (Modifier.isTransient(modifiers))
					continue;
				
				if (Modifier.isStatic(modifiers))
					continue;

				if (Modifier.isFinal(modifiers))
					continue;
//
//
//				if (modifiers >= 128)
//					continue;

				f.setAccessible(true);
				Object value = f.get(obj);
				
				map.put(key, value);

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return map;
	}
	
//	public static void toBeanList(Map<String,Object> map, List<Para> list){
//
//		for (Para para : list){
//			Class clz = para.getClass();
//			para.setValue(toObject(para.getClass(), map));
//		}
//
//	}
	
	public static Map<String,Object> toJsonableMap(Map<String,Object> stringKeyMap){
		Map<String,Object> jsonableMap = new HashMap<String,Object>();
		for (Entry<String, Object> es : stringKeyMap.entrySet()){
			String stringKey = es.getKey();
			if (stringKey.contains(".")){
				stringKey = stringKey.replace(".", "->");
				String[] arr = stringKey.split("->");
				String jsonKey = arr[0];
				String propKey = arr[1];
				Object obj = jsonableMap.get(jsonKey);
				Map<String,Object> objMap = null;
				if (Objects.isNull(obj)){
					objMap = new HashMap<String,Object>();
					jsonableMap.put(jsonKey, objMap);
				}else {
					objMap = (Map<String,Object>) obj;
				}
				objMap.put(propKey, es.getValue());
			}else{
				jsonableMap.put(stringKey, es.getValue());
			}
		}
		return jsonableMap;
	}
	
	public static List<Map<String,Object>> toJsonableMapList (List<Map<String,Object>> stringKeyList){
		
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		
		for (Map<String,Object> map : stringKeyList){
			Map<String,Object> jsonKeyMap = toJsonableMap(map);
			list.add(jsonKeyMap);
		}
		
		return list;
	}
	
	public static List<String> toStringKeyList(Map<String,Object> jonsableMap){
		List<String> list = new ArrayList<String>();
		
		for (Entry<String,Object> entry : jonsableMap.entrySet()){
			String key = entry.getKey();
			Object obj = entry.getValue();
			if (!Objects.isNull(obj)){
				Map<String,Object> map = (Map<String,Object>)obj;
				for (Entry<String,Object> es : map.entrySet()){
					String str = key + "." + es.getKey();
					list.add(str);
				}
			}
		}
		
		return list;
	}

}
